Home:ALL Converter>Generate EC keypair using AndroidKeyStore < Api23

Generate EC keypair using AndroidKeyStore < Api23

Ask Time:2019-07-15T23:15:57         Author:kyo171

Json Formatter

Unable to generate EC Keypair using AndroidKeystore provider one < api23 devices.

According to AndroidKeyStore documentation

Prior to API Level 23, EC keys can be generated using KeyPairGenerator of algorithm "RSA" initialized KeyPairGeneratorSpec whose key type is set to "EC" using setKeyType(String). EC curve name cannot be specified using this method -- a NIST P-curve is automatically chosen based on the requested key size.

Below Api 23, I should be able to generate an EC keypair using the AndroidKeyStore provider as the code snippet shown below which is what i am doing currently.

val ecGenParameterSpec = ECGenParameterSpec("P-256")
val spec = KeyPairGeneratorSpec.Builder(context)
                .setAlias(ALIAS)
                .setSubject(X500Principal("CN=example"))
                .setSerialNumber(BigInteger.ONE)
                .setKeyType("EC")
                .setAlgorithmParameterSpec(ecGenParameterSpec)
                .setStartDate(start)
                .setEndDate(end)
                .build()
                val keyGen = KeyPairGenerator.getInstance("RSA", androidKeyStoreProvider)
keyGen.initialize(spec, SecureRandom())
keyGen.generateKeyPair()

However i keep getting java.lang.UnsupportedOperationException: private key value S cannot be extracted.

Am i doing something wrong during the generating of the EC key pair using AndroidKeyStore?

or have i mis-interpreted the official AndroidKeyStore documentation for KeyPairGenerator?

Below is my stacktrace from one of the devices(oneplus one) that i tried it with. I have tried on multiple devices on api 21 and 22.

Devices - Asus zenfone2 (api21), nexus 4(api22), oneplus one(api22), redmi note2 (api21)

No pending exception expected: java.lang.UnsupportedOperationException: private key value S cannot be extracted
  at java.math.BigInteger com.android.org.conscrypt.OpenSSLECPrivateKey.getS() (OpenSSLECPrivateKey.java:141)
  at com.android.org.bouncycastle.crypto.params.AsymmetricKeyParameter com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil.gen
   eratePrivateKeyParameter(java.security.PrivateKey) (ECUtil.java:188)
  at void com.android.org.bouncycastle.jcajce.provider.asymmetric.ec.SignatureSpi.engineInitSign(java.security.PrivateKey) (SignatureSpi.java:
   61)
  at void java.security.Signature$SignatureImpl.engineInitSign(java.security.PrivateKey) (Signature.java:679)
  at void java.security.Signature.initSign(java.security.PrivateKey) (Signature.java:330)
  at byte[] org.conscrypt.CryptoUpcalls.signDigestWithPrivateKey(java.security.PrivateKey, byte[], java.lang.String) (SourceFile:101)
  at byte[] org.conscrypt.CryptoUpcalls.ecSignDigestWithPrivateKey(java.security.PrivateKey, byte[]) (SourceFile:67)
  at byte[] org.conscrypt.NativeCrypto.EVP_DigestSignFinal(org.conscrypt.NativeRef$EVP_MD_CTX) (SourceFile:-2)
  at byte[] org.conscrypt.OpenSSLSignature.engineSign() (SourceFile:226)
  at byte[] java.security.Signature$SignatureImpl.engineSign() (Signature.java:659)
  at byte[] java.security.Signature.sign() (Signature.java:368)
  at byte[] com.android.org.bouncycastle.x509.X509Util.calculateSignature(com.android.org.bouncycastle.asn1.DERObjectIdentifier, java.lang.Str
   ing, java.security.PrivateKey, java.security.SecureRandom, com.android.org.bouncycastle.asn1.ASN1Encodable) (X509Util.java:248)
  at java.security.cert.X509Certificate com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(java.security.PrivateKey, java.s
   ecurity.SecureRandom) (X509V3CertificateGenerator.java:434)
  at java.security.cert.X509Certificate com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(java.security.PrivateKey) (X509V
   3CertificateGenerator.java:412)
  at java.security.KeyPair android.security.AndroidKeyPairGenerator.generateKeyPair() (AndroidKeyPairGenerator.java:133)
  at java.security.KeyPair java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair() (KeyPairGenerator.java:276)

Update

Found the issue, i was using Google Conscrypt Android in my application.

Security.insertProviderAt(Conscrypt.newProvider(), 1)

Somehow when i am using Conscrypt provider in my application, AndroidKeyStore fails to generate an EC keypair. Removing the use of Conscrypt seems to solve the issue.

Author:kyo171,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/57042699/generate-ec-keypair-using-androidkeystore-api23
yy